﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CRM.Extensions;
using CRM.Models;
using CRM.Services;
using CRM.Services.Customer;
using CRM.ViewModels.Customer;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace CRM.Controllers.Customer
{
    using static CRM.Services.Customer.CustomerService;
    using CustomerModel = Models.Customer;

    [Route("api/[controller]")]
    [ApiController]
    public class CustomerController : BaseController
    {
        private readonly MyDbContext _dbContext;
        private readonly UserManager<User> _userManager;
        private readonly CustomerService _customerService;
        private readonly GlobalSearchService _globalSearchService;

        public CustomerController(MyDbContext dbContext, UserManager<User> userManager, CustomerService customerService,
            GlobalSearchService globalSearchService)
        {
            _dbContext = dbContext;
            _userManager = userManager;
            _customerService = customerService;
            _globalSearchService = globalSearchService;
        }

        [HttpPost(nameof(List))]
        public async Task<ResultStruct> List(CustomerListVM Scope)
        {
            var user = await _userManager.GetUserAsync(User);

            var Model = _dbContext.Customer as IQueryable<CustomerModel>;

            var actionArr = Enum.GetValues(typeof(CustomerListVM.ActionType)).ToArrayDynamic();

            if (actionArr.Contains(Scope.Action))
            {
                //我的客户
                if (Scope.Action == CustomerListVM.ActionType.My)
                {
                    Model = Model.Where(m => m.OemId == user.OemId && m.UserId == user.Id && m.IsPrivate == 1);
                }

                //意向客户
                if (Scope.Action == CustomerListVM.ActionType.Intention)
                {
                    Model = Model.Where(m =>
                        m.OemId == user.OemId && m.UserId == user.Id && m.IsIntention == 1 && m.IsPrivate == 1);
                }

                //公海客户
                if (Scope.Action == CustomerListVM.ActionType.Water)
                {
                    Model = Model.Where(m => m.OemId == user.OemId && m.IsPrivate == 0);
                }
            }
            else
            {
                return Error(new object(), "类型错误");
            }

            if (Scope.Type > 0)
            {
                Model = Model.Where(m => (int)m.Type == Scope.Type);
            }

            if (!string.IsNullOrEmpty(Scope.Name))
            {
                Model = Model.Where(m => m.Name == Scope.Name);
            }

            if (!string.IsNullOrEmpty(Scope.Mobile))
            {
                Model = Model.Where(m => m.Mobile == Scope.Mobile);
            }

            var statusArr = new List<int> { 0, 1 };

            if (statusArr.Contains(Scope.Status))
            {
                Model = Model.Where(m => m.DealStatus == Scope.Status);
            }
            else if (Scope.Status == 2)
            {
                Model = Model.Where(m => m.FollowAt != null);
            }
            else if (Scope.Status == 3)
            {
                Model = Model.Where(m => m.FollowAt == null);
            }

            var List = await Model
                .OrderByDescending(m => m.Id)
                .Include(m => m.Group)
                .Include(m => m.Source)
                .Include(m => m.User)
                .Include(m => m.BelongUser)
                .Include(m => m.Labels)
                .ToPaginateAsync(Request);
            return Success(List);
        }

        [HttpPost(nameof(SetAttention))]
        public async Task<ResultStruct> SetAttention(CustomerModel customer)
        {
            if (customer.Id <= 0)
            {
                return Error(new object(), "参数错误");
            }

            var user = await _userManager.GetUserAsync(User);
            var row = await _dbContext.Customer.Where(m => m.Id == customer.Id && m.OemId == user.OemId)
                .FirstOrDefaultAsync();

            if (row == null)
            {
                return Error(new object(), "数据不存在");
            }

            if (customer.Attention < 0 || customer.Attention > 5)
            {
                return Error(new object(), "参数错误");
            }

            row.Attention = customer.Attention;
            var status = await _dbContext.SaveChangesAsync();

            if (status >= 1)
            {
                return Success(new object(), "更新成功");
            }

            return Error(new object(), "更新失败");
        }

        [HttpPost(nameof(SetCustomerGroup))]
        public async Task<ResultStruct> SetCustomerGroup(SetGroupVM Data)
        {
            var res = await _customerService.SetGroup(Data.Group, Data.Ids, SetDataType.Customer);
            return res ? Success(new(), "设置成功") : Error(message: _customerService.Error);
        }

        [HttpGet("Log/{id:int}")]
        public async Task<ResultStruct> Log(int Id)
        {
            var list = await _dbContext.CustomerOperationLog.Where(m => m.CustomerId == Id).Include(m => m.User)
                .OrderByDescending(m => m.CreatedAt).ToListAsync();
            return Success(list);
        }

        /// <summary>
        /// 从全球搜索添加客户
        /// </summary>
        /// <param name="id"></param>
        /// <param name="isPrivate"></param>
        /// <returns></returns>
        [HttpPost("[action]/{id:int}")]
        public async Task<ResultStruct> DataSearchCreate(int id, [FromQuery] int isPrivate)
        {
            var user = _customerService.CurrentUser;
            var domain = await _dbContext.KeywordsDomains
                .FirstOrDefaultAsync(m => m.Id == id);
            if (null == domain)
            {
                return Error(message: "记录不存在");
            }
            await _globalSearchService.GetClueList(domain);
            if (!string.IsNullOrEmpty(_globalSearchService.Error))
            {
                return Error(message: _globalSearchService.Error);
            }

            if (domain.Employees is { Count :<= 0}) return Error(message: "未查询到有效客户");


            var query = from company in _dbContext.CustomerCompany
                        where company.OemId == user.OemId
                        where company.UserId == user.Id
                        where company.From == CustomerCompany.FromType.GlobalSearch
                        where company.RelationId == id
                        select company;
            var row = await query.FirstOrDefaultAsync();

            if (null != row)
            {
                return Error(message: "客户已添加");
            }
            var trans  =  await _dbContext.Database.BeginTransactionAsync();
            try
            {
                row = new CustomerCompany()
                {
                    RelationId = id,
                    Name = domain.Title,
                    NameHash = domain.Title.GetFixedHashCode(),
                    From = CustomerCompany.FromType.GlobalSearch,
                    IsExistPrivate = isPrivate == 0
                    ? CustomerCompany.IsExistPrivateType.Yes
                    : CustomerCompany.IsExistPrivateType.NO,
                    IsExistMy = isPrivate == 0
                    ? CustomerCompany.IsExistMyType.NO
                    : CustomerCompany.IsExistMyType.Yes,
                    Url = domain.Url,
                    UserId = user.Id,
                    GroupId = user.GroupId,
                    CompanyId = user.CompanyId,
                    OemId = user.OemId,
                };
                _dbContext.Add(row);

                var customers = domain.Employees.Select(e => new CustomerModel()
                {
                    Name = $"{e.FirstName} {e.LastName}",
                    Email = e.BusinessEmail,
                    PersonalEmail = e.PersonalEmail,
                    LinkedinUrl = e.LinkedinId.ToString(),
                    JobTitle = e.JobTitle,
                    Type = 1,
                    IsPrivate = isPrivate,
                    Block = row,
                    UserId = user.Id,
                    GroupId = user.GroupId,
                    CompanyId = user.CompanyId,
                    OemId = user.OemId,
                    BelongAt = DateTime.Now,
                });
                var res = await _customerService.Create(customers);
                if (!res)
                {
                    await trans.RollbackAsync();
                    return Error(message: _customerService.Error);
                }
                await _dbContext.SaveChangesAsync();

                await trans.CommitAsync();
                return Success();
            } catch (Exception)
            {
                return Error(message: _customerService.Error);
            }
        }

        [HttpPost("[action]")]
        public async Task<ResultStruct> Create(CustomerModel customer)
        {
            var res = await _customerService.Create(customer);
            return res ? Success() : Error(message: _customerService.Error);
        }

        [HttpGet("{id:int}")]
        public async Task<ResultStruct> Get(int id)
        {
            var user = await _userManager.GetUserAsync(User);
            var row = await _dbContext.Customer
                .Where(m => m.Id == id && m.OemId == user.OemId)
                .Include(m => m.BelongUser)
                .Include(m => m.User)
                .Include(m => m.Group)
                .Include(m => m.Source)
                .Include(m => m.Labels)
                .AsSplitQuery()
                .FirstOrDefaultAsync();
            return row == null ? Error(new object(), "获取失败") : Success(row, "获取成功");
        }

        [HttpPut("{id}")]
        public async Task<ResultStruct> Update(CustomerModel customer)
        {
            if (customer.Id <= 0)
            {
                return Error(new object(), "参数错误");
            }

            var user = await _userManager.GetUserAsync(User);
            var row = await _dbContext.Customer.Where(m => m.Id == customer.Id && m.OemId == user.OemId)
                .FirstOrDefaultAsync();

            if (row == null)
            {
                return Error(new object(), "数据不存在");
            }

            if (user.Company.IsRepetitionAllowed == Company.IsRepetitionAllowedType.ENABLE)
            {
                //todo 用户ID
                //去重
                var repeat = await _dbContext.Customer
                .Where(m => m.Email == customer.Email && m.Id != customer.Id && m.OemId == user.OemId)
                .FirstOrDefaultAsync();

                if (repeat != null)
                {
                    return Error(new object(), "该客户已存在");
                }

            }

            var Content = "";

            if (row.Name != customer.Name)
            {
                Content += $"将客户名称 由{row.Name}修改为{customer.Name}。\r\n";
            }

            if (row.Mobile != customer.Mobile)
            {
                Content += $"将客户手机号 由{row.Mobile}修改为{customer.Mobile}。\r\n";
            }

            if (row.Email != customer.Email)
            {
                Content += $"将客户邮箱 由{row.Email}修改为{customer.Email}。\r\n";
            }

            if (row.JobTitle != customer.JobTitle)
            {
                var JobTitleOrigin = !string.IsNullOrEmpty(row.JobTitle) ? row.JobTitle : "无";

                Content += $"将客户职称 由{JobTitleOrigin}修改为{customer.JobTitle}。\r\n";
            }


            if (row.CompanyTel != customer.CompanyTel)
            {
                var CompanyTelOrigin = !string.IsNullOrEmpty(row.CompanyTel) ? row.CompanyTel : "无";

                Content += $"将客户公司电话 由{CompanyTelOrigin}修改为{customer.CompanyTel}。\r\n";
            }

            if (row.LinkedinUrl != customer.LinkedinUrl)
            {
                var LinkedinUrlOrigin = !string.IsNullOrEmpty(row.LinkedinUrl) ? row.LinkedinUrl : "无";

                Content += $"将客户领英网址 由{LinkedinUrlOrigin}修改为{customer.LinkedinUrl}。\r\n";
            }


            var Time = DateTime.Now;
            row.UpdatedAt = Time;
            row.Name = customer.Name;
            row.Email = customer.Email;
            row.Mobile = customer.Mobile;
            row.Attention = customer.Attention;
            row.Remarks = customer.Remarks;
            row.CompanyTel = customer.CompanyTel;
            row.JobTitle = customer.JobTitle;
            row.LinkedinUrl = customer.LinkedinUrl;
            if (customer.SourceId == 0)
            {
                row.SourceId = null;
            }
            else
            {
                row.SourceId = customer.SourceId;
            }

            if (customer.GroupId == 0)
            {
                row.GroupId = null;
            }
            else
            {
                row.GroupId = customer.GroupId;
            }

            row.Type = customer.Type;
            row.Remarks = customer.Remarks;


            CustomerOperationLog Log = new()
            {
                CustomerId = row.Id,
                Content = Content,
            };

            var Transaction = _dbContext.Database.BeginTransaction();
            try
            {
                await _dbContext.SaveChangesAsync();
                if (Content != "")
                {
                    await (new OperationLogService(_dbContext, HttpContext, _userManager)).AddLogAsync(Log);
                }

                Transaction.Commit();
            }
            catch (Exception e)
            {
                Transaction.Rollback();
                return Error(new object(), e.Message);
            }

            return Success(new object(), "更新成功");
        }

        [HttpPost(nameof(SetDealStatus))]
        public async Task<ResultStruct> SetDealStatus(SeStateVM Data)
        {
            var CheckValue = new List<int>() { 0, 1 };

            if (!CheckValue.Contains(Data.Value))
            {
                return Error(new object(), "参数错误");
            }

            var Status = Data.Value;

            if (Data.Ids.Count <= 0)
            {
                return Error(new object(), "参数错误!");
            }

            var Ids = Data.Ids;
            var user = await _userManager.GetUserAsync(User);

            var List = await _dbContext.Customer.Where(m => Ids.Contains(m.Id) && m.OemId == user.OemId).ToListAsync();

            if (List.Count <= 0 || List.Count != Ids.Count)
            {
                return Error(new object(), "客户不存在");
            }

            List<CustomerOperationLog> logs = new() { };

            foreach (var item in List)
            {
                if (item.DealStatus != Status)
                {
                    var Content = "";
                    if (Status == 1)
                    {
                        Content =
                            $"将客户成交状态 由{CustomerModel.DealStatusEnum.Unsettled.GetDescription()}修改为{CustomerModel.DealStatusEnum.Closed.GetDescription()}。";
                    }
                    else
                    {
                        Content =
                            $"将客户成交状态 由{CustomerModel.DealStatusEnum.Closed.GetDescription()}修改为{CustomerModel.DealStatusEnum.Unsettled.GetDescription()}。";
                    }

                    logs.Add(
                        new CustomerOperationLog()
                        {
                            CustomerId = item.Id,
                            Content = Content,
                        }
                    );
                }

                item.DealStatus = Status;
            }

            var Transaction = _dbContext.Database.BeginTransaction();
            try
            {
                await _dbContext.SaveChangesAsync();
                if (logs.Count > 0)
                {
                    await (new OperationLogService(_dbContext, HttpContext, _userManager)).AddLogAsync(logs);
                }

                Transaction.Commit();
            }
            catch (Exception e)
            {
                Transaction.Rollback();
                return Error(new object(), e.Message);
            }

            return Success(new object(), "设置成功");
        }

        [HttpPost(nameof(SetIsIntention))]
        public async Task<ResultStruct> SetIsIntention(SeStateVM Data)
        {
            var res = await _customerService.SetIsIntention(Data.Value, Data.Ids, SetDataType.Customer);
            return res ? Success(new(), "操作成功") : Error(message: _customerService.Error);
        }

        [HttpPost(nameof(SetIsPrivate))]
        public async Task<ResultStruct> SetIsPrivate(SeStateVM Data)
        {
            var BlockId = Data.BlockId;

            var BlockInfo = await _customerService.CustomerCompanyCondition(true).Where(m => m.Id == BlockId).FirstOrDefaultAsync();

            if (BlockInfo == null)
            {
                return Error(new object(), "数据不存在");
            }

            var res = await _customerService.SetIsPrivate(Data.Value, Data.Ids, BlockInfo);
            return res ? Success(new(), "操作成功") : Error(message: _customerService.Error);
        }

        [HttpPost("SetCustomerLabel")]
        public async Task<ResultStruct> SetCustomerLabel(SetLabelVM Data)
        {
            var res = await _customerService.SetLabel(Data.Label, Data.Ids, SetDataType.Customer);
            return res ? Success(new(), "设置成功") : Error(message: _customerService.Error);
        }

        [HttpPost(nameof(SetCustomerSource))]
        public async Task<ResultStruct> SetCustomerSource(SetSourceVM Data)
        {
            var res = await _customerService.SetSource(Data.Source, Data.Ids, SetDataType.Customer);
            return res ? Success(new(), "设置成功") : Error(message: _customerService.Error);
        }

        [HttpPost(nameof(getAllIds))]
        public async Task<ResultStruct> getAllIds(CustomerListVM Scope)
        {
            var user = await _userManager.GetUserAsync(User);
            var Model = _dbContext.Customer as IQueryable<CustomerModel>;

            var actionArr = Enum.GetValues(typeof(CustomerListVM.ActionType)).ToArrayDynamic();

            if (actionArr.Contains(Scope.Action))
            {
                //我的客户
                if (Scope.Action == CustomerListVM.ActionType.My)
                {
                    Model = Model.Where(m => m.OemId == user.OemId && m.UserId == user.Id && m.IsPrivate == 1);
                }

                //意向客户
                if (Scope.Action == CustomerListVM.ActionType.Intention)
                {
                    Model = Model.Where(m =>
                        m.OemId == user.OemId && m.UserId == user.Id && m.IsIntention == 1 && m.IsPrivate == 1);
                }
            }
            else
            {
                return Error(new object(), "类型错误");
            }

            var List = await Model
                .OrderByDescending(m => m.Id)
                .Select(m => m.Id)
                .ToListAsync();
            var max = 300;
            if (List.Count > max)
            {
                return Error(new object(), $"导出数量不可超过{max}");
            }

            return Success(List);
        }

        [HttpPost(nameof(GetIds))]
        public async Task<ResultStruct> GetIds(CustomerListVM Scope)
        {
            var user = await _userManager.GetUserAsync(User);
            var Model = _dbContext.Customer as IQueryable<CustomerModel>;

            var actionArr = Enum.GetValues(typeof(CustomerListVM.ActionType)).ToArrayDynamic();

            if (actionArr.Contains(Scope.Action))
            {
                //我的客户
                if (Scope.Action == CustomerListVM.ActionType.My)
                {
                    Model = Model.Where(m => m.OemId == user.OemId && m.UserId == user.Id && m.IsPrivate == 1);
                }

                //意向客户
                if (Scope.Action == CustomerListVM.ActionType.Intention)
                {
                    Model = Model.Where(m =>
                        m.OemId == user.OemId && m.UserId == user.Id && m.IsIntention == 1 && m.IsPrivate == 1);
                }

                //公海客户
                if (Scope.Action == CustomerListVM.ActionType.Water)
                {
                    Model = Model.Where(m => m.OemId == user.OemId && m.IsPrivate == 0);
                }
            }
            else
            {
                return Error(new object(), "类型错误");
            }

            if (Scope.Type > 0)
            {
                Model = Model.Where(m => (int)m.Type == Scope.Type);
            }

            if (!string.IsNullOrEmpty(Scope.Name))
            {
                Model = Model.Where(m => m.Name == Scope.Name);
            }

            if (!string.IsNullOrEmpty(Scope.Mobile))
            {
                Model = Model.Where(m => m.Mobile == Scope.Mobile);
            }

            var statusArr = new List<int> { 0, 1 };

            if (statusArr.Contains(Scope.Status))
            {
                Model = Model.Where(m => m.DealStatus == Scope.Status);
            }
            else if (Scope.Status == 2)
            {
                Model = Model.Where(m => m.FollowAt != null);
            }
            else if (Scope.Status == 3)
            {
                Model = Model.Where(m => m.FollowAt == null);
            }

            var List = await Model
                .OrderByDescending(m => m.Id)
                .Select(m => m.Id)
                .ToListAsync();
            return Success(List);
        }


        public record EmailVm(string Email);

        [HttpPost(nameof(GetIdByEmail))]
        public async Task<ResultStruct> GetIdByEmail(EmailVm emailVm)
        {
            var email = emailVm.Email;
            var user = await _userManager.GetUserAsync(User);

            var row = await _dbContext.Customer.Where(m => m.OemId == user.OemId && m.Email == email)
                .FirstOrDefaultAsync();

            if (row == null)
            {
                return Success(null, "邮箱不存在");
            }

            GetIdByEmailVM Result = new GetIdByEmailVM()
            {
                Id = row.Id,
                Name = row.Name,
                Email = row.Email,
            };
            return Success(Result, "找到相关数据");
        }

        [HttpPost(nameof(BatchGetIdByEmail))]
        public async Task<ResultStruct<IEnumerable<GetIdByEmailVM>>> BatchGetIdByEmail(List<string> emailList)
        {
            var user = await _userManager.GetUserAsync(User);

            var list = await  _dbContext.Customer.Where(m => m.OemId == user.OemId && emailList.Contains(m.Email))
                .Select(c => new GetIdByEmailVM{ Email = c.Email, Name = c.Name, Id = c.Id })
                .AsNoTracking()
                .ToListAsync();
            var dic = list.Distinct().ToDictionary(c => c.Email, c => c);

            var result = emailList.Select(e => dic.TryGetValue(e, out var value)
                ? value
                : new GetIdByEmailVM()
                {
                    Id = null,
                    Name = "暂无",
                    Email = e
                });
            return SuccessGeneric(result, "找到相关数据");
        }

        [HttpGet(nameof(GetCustomerSelectionOptions))]
        public async Task<ResultStruct> GetCustomerSelectionOptions([FromQuery] String type)
        {
            var model = _dbContext.Customer;
            var tep = await model.ToListAsync();
            // object temp = null;
            object temp = null;
            switch (type)

            {
                case "byGroup":
                    var groupIds = tep.Select(m => m.GroupId).Distinct();
                    _ = await _dbContext.CustomerGroup.Where(m => groupIds.Contains(m.Id)).ToListAsync();
                    var tem = _dbContext.CustomerGroup.Local.AsQueryable()
                        .Include(m => m.Customers)
                        .Select(m => new
                        {
                            Label = m.Name,
                            Value = m.Id,
                            Children = m.Customers.Select(l => new
                            { Label = l.Name + "【" + l.Email + "】", Value = l.Id, Email = l.Email })
                        }).ToList();
                    temp = tem.Prepend(new
                    {
                        Label = "暂无分组",
                        Value = 0,
                        Children = tep.Where(l => l.GroupId == null).Select(l =>
                            new { Label = l.Name + "【" + l.Email + "】", Value = l.Id, Email = l.Email })
                    }).ToList();
                    break;
                    // case "bySource":
                    //     var temp = _dbContext.CustomerGroup.Local.AsQueryable();
                    //   break;
                    // case "byType":
                    //     var temp = _dbContext.CustomerGroup.Local.AsQueryable();
                    //   break;
                    // case "byTag":
                    //     var temp = _dbContext.CustomerGroup.Local.AsQueryable();
                    //   break;
                    // /* 您可以有任意数量的 case 语句 */
                    // default : /* 可选的 */
                    //     var temp = _dbContext.CustomerGroup.Local.AsQueryable();
                    //     break; 
            }

            // var temp = _dbContext.EmailConfigGroup.Local.AsQueryable().Include(m => m.EmailConfigs).Select(m => new
            // {
            //     Label = m.Name,
            //     Value = m.Id,
            //     Children = m.EmailConfigs.Select(l => new {Label=l.EmailAddress, Value=l.Id})
            // }).ToList();
            // temp = temp.Prepend(new {
            //     Label = "暂无分组",
            //     Value =0,
            //     Children = tep.Where(l => l.EmailConfigGroupId == 0).Select(l => new {Label = l.EmailAddress, Value=l.Id })
            // }).ToList();

            // return Success(new { listOfCustomerMailbox = temp });
            return Success(new { listOfCustomerMailbox = temp });
        }


        [HttpDelete("{id}")]
        public async Task<ResultStruct> Delete(int id)
        {
            var CustomerModel = _customerService.CustomnerCondition();

            var row = await CustomerModel.Where(m => m.Id == id).FirstOrDefaultAsync();

            if (row == null)
            {
                return Error(new object(), "数据不存在");
            }

            var Transaction = _dbContext.Database.BeginTransaction();
            try
            {
                _dbContext.Remove(row);
                //操作日志
                var log = await _dbContext.CustomerOperationLog.Where(m => m.CustomerId == id).ToListAsync();
                _dbContext.RemoveRange(log);
                //跟进记录
                var follow = await _dbContext.CustomerFollow.Where(m => m.CustomerId == id).ToListAsync();
                _dbContext.RemoveRange(follow);
                await _dbContext.SaveChangesAsync();
                Transaction.Commit();
            }
            catch (Exception)
            {
                Transaction.Rollback();
                return Error(new object(), "删除失败");
            }

            return Success(new object(), "删除成功");
        }
    }
}